package cn.sciento.boot.iam.field.handler;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import org.apache.commons.lang3.reflect.FieldUtils;
import cn.sciento.boot.iam.field.dto.FieldPermission;
import cn.sciento.mybatis.domian.SecurityToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;

public abstract class SecurityTokenObjectRecursiveHandler implements FieldPermissionHandler {
  private static final Logger logger = LoggerFactory.getLogger(SecurityTokenObjectRecursiveHandler.class);

  public SecurityTokenObjectRecursiveHandler() {
  }

  protected void recursive(List<FieldPermission> fieldPermissionList, Object obj, SecurityTokenObjectRecursiveHandler.Handler handler) {
    this.recursive(null, fieldPermissionList, obj, handler);
  }

  protected void recursive(String parentFieldName, List<FieldPermission> fieldPermissionList, Object obj, SecurityTokenObjectRecursiveHandler.Handler handler) {
    if (obj != null) {
      if (obj instanceof ResponseEntity) {
        this.recursive(parentFieldName, fieldPermissionList, ((ResponseEntity)obj).getBody(), handler);
      } else if (obj instanceof Collection) {
        Iterator var13 = ((Collection)obj).iterator();

        while(var13.hasNext()) {
          Object item = var13.next();
          this.recursive(parentFieldName, fieldPermissionList, item, handler);
        }

      } else {
        if (obj instanceof SecurityToken && !CollectionUtils.isEmpty(fieldPermissionList)) {
          Field[] var5 = obj.getClass().getDeclaredFields();
          int var6 = var5.length;

          for(int var7 = 0; var7 < var6; ++var7) {
            Field field = var5[var7];
            FieldPermission fieldPermission = this.shouldProcess(fieldPermissionList, this.getFieldName(parentFieldName, field.getName()));
            if (fieldPermission != null) {
              try {
                handler.handler(obj, field.getName(), fieldPermission);
              } catch (Exception var12) {
                logger.error("Error process field.", var12);
              }
            }

            if (SecurityToken.class.isAssignableFrom(field.getType()) && !SecurityToken.class.equals(field.getType())) {
              try {
                this.recursive(this.getFieldName(parentFieldName, field.getName()), fieldPermissionList, FieldUtils.readDeclaredField(obj, field.getName(), true), handler);
              } catch (IllegalAccessException var11) {
                logger.error("Error read field.", var11);
              }
            }
          }
        }

      }
    }
  }

  protected FieldPermission shouldProcess(List<FieldPermission> fieldPermissionList, String fieldName) {
    Iterator var3 = fieldPermissionList.iterator();

    FieldPermission fieldPermission;
    do {
      if (!var3.hasNext()) {
        return null;
      }

      fieldPermission = (FieldPermission)var3.next();
    } while(!Objects.equals(fieldName, fieldPermission.getFieldName()));

    return fieldPermission;
  }

  protected String getFieldName(String parentFieldName, String fieldName) {
    return parentFieldName != null ? parentFieldName + "." + fieldName : fieldName;
  }

  @FunctionalInterface
  public interface Handler {
    void handler(Object obj, String fieldName, FieldPermission fieldPermission) throws Exception;
  }
}
